package org.lds.message.center.core;

import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.lds.message.center.common.Endpoint;
import org.lds.message.center.common.MessageService;
import org.lds.message.center.common.annotation.ExceptionInterceptor;
import org.lds.message.center.common.annotation.Log;
import org.lds.message.center.common.model.ResultDTO;
import org.lds.message.center.common.model.request.CommonRequest;
import org.lds.message.center.common.model.request.PublicRequest;
import org.lds.message.center.common.util.AssertUtil;
import org.lds.message.center.common.util.JsonUtil;
import org.lds.message.center.core.enums.CoreErrorEnum;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@RequiredArgsConstructor
public class DefaultEndpoint implements Endpoint {
    private final MessageServiceFinder messageServiceFinder;

    @Log("发送消息通用端点")
    @ExceptionInterceptor
    @Override
    public ResultDTO common(PublicRequest publicRequest) {
        AssertUtil.assertTrue(Objects.nonNull(publicRequest) && MapUtils.isNotEmpty(publicRequest.getRequest()), CoreErrorEnum.PUBLIC_REQUEST_INVALID);
        Map<String, List<String>> request = publicRequest.getRequest();

        // 类型转换
        Map<MessageService, List<CommonRequest>> commonRequestMap = commonRequestMap(request);

        // check
        commonRequestMap.forEach((messageService, commonRequests) -> commonRequests.forEach(messageService::check));

        // send
        commonRequestMap.forEach((messageService, commonRequests) -> commonRequests.forEach(messageService::send));

        return ResultDTO.success();
    }

    private Map<MessageService, List<CommonRequest>> commonRequestMap(Map<String, List<String>> request) {
        Map<MessageService, List<CommonRequest>> commonRequestMap = new HashMap<>();
        request.forEach((channel, channelRequests) -> {
            MessageService messageService = messageServiceFinder.find(channel);
            if (CollectionUtils.isNotEmpty(channelRequests)) {
                commonRequestMap.put(messageService,
                        channelRequests.stream()
                                .map(text -> to(text, messageService))
                                .collect(Collectors.toList()));
            }
        });
        return commonRequestMap;
    }

    private CommonRequest to(String json, MessageService messageService) {
        Object o = JsonUtil.fromJson(json, messageService.supportClass());
        return (CommonRequest) o;
    }

}
